!======================================================================
!
!    HEEDS (Higher Education Enrollment Decision Support) - A program
!      to create enrollment scenarios for 'next term' in a university
!    Copyright (C) 2012, 2013 Ricolindo L Carino
!
!    This file is part of the HEEDS program.
!
!    HEEDS is free software: you can redistribute it and/or modify
!    it under the terms of the GNU General Public License as published by
!    the Free Software Foundation, either version 3 of the License, or
!    (at your option) any later version.
!
!    HEEDS is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with this program (see the file COPYING.TXT). If not, see
!    <http://www.gnu.org/licenses/>.
!
!    Send inquiries about HEEDS to:
!      Ricolindo L Carino
!      E-mail: Ricolindo.Carino@AcademicForecasts.com
!      Address: 600 Cruise St., Starkville, MS 39759, U.S.A.
!
!======================================================================


module DEPARTMENTS

    use COLLEGES

    implicit none

    type :: typeDEPARTMENT
        character (len=MAX_LEN_DEPARTMENT_CODE) :: Code
        character (len=MAX_DEPARTMENT_NAME_LEN) :: Name
        character (len=1) :: SectionPrefix ! prefix for section codes of classes in dept
        integer :: CollegeIdx
        logical :: hasInfo
    end type typeDEPARTMENT

    type (typeDEPARTMENT), dimension (0:MAX_ALL_DEPARTMENTS) :: Department
    integer :: NumDepartments

    integer, dimension(0:2,MAX_ALL_DEPARTMENTS) :: ScheduleCount ! last section in department

    ! private tokens
    character (len=MAX_LEN_FILE_PATH), private :: fileName
    character (len=MAX_LEN_XML_LINE), private :: line
    integer, private :: unitNum=2, eof, ndels, pos(30)


contains


#include "custom_read_departments.F90"


    subroutine read_departments(path, errNo)

        character(len=*), intent(in) :: path
        integer, intent (out) :: errNo

        logical :: noXML

        call initialize_department (Department(0))
        Department(2:) = Department(0)
        Department(0)%Code = 'ERROR'
        Department(0)%Name = '(ERROR)'
        Department(1)%Code = '(dummy)'
        Department(1)%Name = '(dummy)'
        NumDepartments = 1
        ScheduleCount = 0

        noXML = .false.
        call xml_read_departments(path, errNo) ! try the XML file
        if (errNo/=0) then ! something wrong with XML file
            noXML = .true.
            call  custom_read_departments(path, errNo) ! try custom format
            if (errNo/=0) return ! something still wrong
        end if

        ! add REGISTAR as 'administrative' department for data that does not fit in the 'academic' departments
        NumDepartments = NumDepartments + 1
        call initialize_department (Department(NumDepartments), &
            REGISTRAR, trim(UniversityCode)//' Registrar', '#', NumColleges)

        ! write the XML DEPARTMENTS file?
        if (noXML) call xml_write_departments(path)

        return
    end subroutine read_departments


    subroutine initialize_department (wrkDepartment, tCode, tName, tPrefix, iCollege)

        type(typeDEPARTMENT), intent (out) :: wrkDepartment
        character(len=*), intent (in), optional :: tCode, tName, tPrefix
        integer, intent (in), optional :: iCollege

        if (present(tCode)) then
            wrkDepartment = typeDEPARTMENT(tCode, tName, tPrefix, iCollege, .false.)
        else
            wrkDepartment = typeDEPARTMENT(SPACE, SPACE, SPACE, 0, .false.)
        end if

        return
    end subroutine initialize_department



    function index_to_dept(token)

        integer :: index_to_dept
        character (len=MAX_LEN_DEPARTMENT_CODE), intent(in) :: token

        integer :: i

        index_to_dept = 0
        do i=1,NumDepartments
            if (token==Department(i)%Code) then
                index_to_dept = i
                exit
            end if
        end do

        return
    end function index_to_dept


    subroutine xml_write_departments(path)

        character(len=*), intent(in) :: path
        integer :: ldx

        ! training only?
        if (noWrites) return

        fileName = trim(dirXML)//trim(path)//'DEPARTMENTS.XML'
        call xml_open_file(unitNum, XML_ROOT_DEPARTMENTS, fileName, ldx)
        write(unitNum,AFORMAT) &
        '    <comment>', &
        '        Generated by '//PROGNAME//VERSION//' on '//currentDate(1:4)// &
                    FSLASH//currentDate(5:6)//FSLASH//currentDate(7:8), &
        '        Code - department code', &
        '        Name - long name of department', &
        '        College - mother unit of the department', &
        '        SectionPrefix - prefix of codes for classes in this department', &
        '    </comment>'

        do ldx = 2,NumDepartments-1
            call xml_write_character(unitNum, indent0, 'Department')
            call xml_write_character(unitNum, indent1, 'Code', Department(ldx)%Code)
            call xml_write_character(unitNum, indent1, 'Name', Department(ldx)%Name)
            call xml_write_character(unitNum, indent1, 'College', College(Department(ldx)%CollegeIdx)%Code)
            if (Department(ldx)%SectionPrefix/=SPACE) &
                call xml_write_character(unitNum, indent1, 'SectionPrefix', Department(ldx)%SectionPrefix)
            call xml_write_character(unitNum, indent0, '/Department')
        end do

        call xml_close_file(unitNum, XML_ROOT_DEPARTMENTS)

        return
    end subroutine xml_write_departments


    subroutine xml_read_departments(path, errNo)

        character(len=*), intent(in) :: path
        integer, intent (out) :: errNo

        integer :: j
        character(len=MAX_LEN_XML_LINE) :: value
        character(len=MAX_LEN_XML_TAG) :: tag
        type(typeDEPARTMENT) :: wrkDepartment
        character (len=MAX_LEN_COLLEGE_CODE) :: tColl

        ! open file, return on any error
        fileName = trim(dirXML)//trim(path)//'DEPARTMENTS.XML'
        call xml_open_file(unitNum, XML_ROOT_DEPARTMENTS, fileName, errNo, forReading)
        if (errNo/=0) return

        ! examine the file line by line
        do

            read(unitNum, AFORMAT, iostat=eof) line
            if (eof<0) exit

            ! get tag and value if any; exit on any error
            call xml_parse_line(line, tag, value, eof)
            if (eof/=0) exit

            select case (trim(tag))

                case ('Department') ! initialize temporary department data
                    call initialize_department (wrkDepartment)

                case ('Code')
                    wrkDepartment%Code = adjustl(value)

                case ('Name')
                    wrkDepartment%Name = adjustl(value)

                case ('College')
                    tColl = adjustl(value)
                    j = index_to_college(tColl)
                    if (j==0) j = NumColleges ! use ADMINISTRATION for invalid college code
                    wrkDepartment%CollegeIdx = j

                case ('SectionPrefix')
                    wrkDepartment%SectionPrefix = adjustl(value)

                case ('/Department') ! add temporary department data to Department()
                    if (index(wrkDepartment%Code,trim(REGISTRAR))>0) cycle ! add at the end
                    NumDepartments = NumDepartments + 1
                    call check_array_bound (NumDepartments, MAX_ALL_DEPARTMENTS, 'MAX_ALL_DEPARTMENTS')
                    Department(NumDepartments) = wrkDepartment

                case default
                   ! do nothing

            end select

        end do

        call xml_close_file(unitNum)

        return
    end subroutine xml_read_departments


end module DEPARTMENTS
